package org.quincy.rock.core.dao;

import java.util.List;
import java.util.Map;

import org.quincy.rock.core.dao.sql.Predicate;
import org.quincy.rock.core.dao.sql.Sort;
import org.quincy.rock.core.vo.PageSet;
import org.quincy.rock.core.vo.Vo;

/**
 * <b>业务层对象接口。</b>
 * <p><b>详细说明：</b></p>
 * <!-- 在此添加详细说明 -->
 * 无。
 * 
 * @version 1.0
 * @author wks
 * @since 1.0
 */
public interface IService<T extends Vo<Long>> {
	/**
	 * <b>添加新实体对象。</b>
	 * <p><b>详细说明：</b></p>
	 * <!-- 在此添加详细说明 -->
	 * 无。
	 * @param entity 实体对象
	 * @param ignoreNullValue 是否忽略空值
	 * @param excluded 排除的属性
	 * @return 是否成功
	 */
	public boolean insert(T entity, boolean ignoreNullValue, String... excluded);

	/**
	 * <b>更新实体对象。</b>
	 * <p><b>详细说明：</b></p>
	 * <!-- 在此添加详细说明 -->
	 * 无。
	 * @param entity 实体对象
	 * @param ignoreNullValue 是否忽略空值
	 * @param where where条件，如果为空，则按照主键进行更新
	 * @param excluded 排除的属性
	 * @return 是否成功
	 */
	public boolean update(T entity, boolean ignoreNullValue, Predicate where, String... excluded);

	/**
	 * <b>使用Map更新数据。</b>
	 * <p><b>详细说明：</b></p>
	 * <!-- 在此添加详细说明 -->
	 * 无。
	 * @param voMap 数据Map
	 * @param where where条件，如果为空，则按照主键进行更新
	 * @return 是否成功
	 */
	public boolean updateMap(Map<String, Object> voMap, Predicate where);

	/**
	 * <b>删除实体对象。</b>
	 * <p><b>详细说明：</b></p>
	 * <!-- 在此添加详细说明 -->
	 * 无。
	 * @param id 要删除的实体主键id
	 * @return 是否成功
	 */
	public boolean delete(long id);

	/**
	 * <b>删除多个实体对象。</b>
	 * <p><b>详细说明：</b></p>
	 * <!-- 在此添加详细说明 -->
	 * 无。
	 * @param ids 主键id列表
	 * @return 是否成功
	 */
	public boolean deleteMore(List<Long> ids);

	/**
	 * <b>删除符合条件的所有数据。</b>
	 * <p><b>详细说明：</b></p>
	 * <!-- 在此添加详细说明 -->
	 * 无。
	 * @param where where条件,如果为null则删除所有
	 * @return 是否成功
	 */
	public boolean deleteAll(Predicate where);

	/**
	 * <b>根据where条件查询记录条数。</b>
	 * <p><b>详细说明：</b></p>
	 * <!-- 在此添加详细说明 -->
	 * 无。
	 * @param where where条件,如果为空则返回总条数
	 * @return 记录条数
	 */
	public long count(Predicate where);

	/**
	 * <b>返回数据是否存在。</b>
	 * <p><b>详细说明：</b></p>
	 * <!-- 在此添加详细说明 -->
	 * 无。
	 * @param id 主建id
	 * @return 数据是否存在
	 */
	public boolean exist(long id);

	/**
	 * <b>根据指定的属性名和值查询是否存在符合条件的数据。</b>
	 * <p><b>详细说明：</b></p>
	 * <!-- 在此添加详细说明 -->
	 * 无。
	 * @param name 属性名称
	 * @param value 属性值
	 * @param ignoreId 忽略的主键id，可以为null
	 * @return 实体对象
	 */
	public boolean existByName(String name, Object value, Long ignoreId);

	/**
	 * <b>查询符合条件的数据是否存在。</b>
	 * <p><b>详细说明：</b></p>
	 * <!-- 在此添加详细说明 -->
	 * 无。
	 * @param where where条件,如果为空判断是否有数据
	 * @return 符合条件的数据是否存在
	 */
	public boolean existByWhere(Predicate where);

	/**
	 * <b>查找一个实体。</b>
	 * <p><b>详细说明：</b></p>
	 * <!-- 在此添加详细说明 -->
	 * 无。
	 * @param id 主键id
	 * @param excluded 排除的属性
	 * @return 实体对象
	 */
	public T findOne(long id, String... excluded);

	/**
	 * <b>查找多个实体。</b>
	 * <p><b>详细说明：</b></p>
	 * <!-- 在此添加详细说明 -->
	 * 无。
	 * @param ids 主键id列表
	 * @param excluded 排除的属性
	 * @return 实体列表
	 */
	public List<T> findMore(List<Long> ids, String... excluded);

	/**
	 * <b>返回符合条件的所有实体列表。</b>
	 * <p><b>详细说明：</b></p>
	 * <!-- 在此添加详细说明 -->
	 * 无。
	 * @param where where条件，如果为空则查询所有数据
	 * @param sort 排序规则
	 * @param excluded 排除的属性
	 * @return 所有的实体列表
	 */
	public List<T> findAll(Predicate where, Sort sort, String... excluded);

	/**
	 * <b>根据指定的属性名和值返回一条数据。</b>
	 * <p><b>详细说明：</b></p>
	 * <!-- 在此添加详细说明 -->
	 * 无。
	 * @param name 属性名称
	 * @param value 属性值
	 * @param excluded 排除的属性
	 * @return 实体对象
	 */
	public T findByName(String name, Object value, String... excluded);

	/**
	 * <b>据指定的属性名和值返回符合条件的所有数据。</b>
	 * <p><b>详细说明：</b></p>
	 * <!-- 在此添加详细说明 -->
	 * 无。
	 * @param name 属性名称
	 * @param value 属性值
	 * @param sort 排序规则
	 * @param excluded 排除的属性
	 * @return 数据列表
	 */
	public List<T> findAllByName(String name, Object value, Sort sort, String... excluded);

	/**
	 * <b>根据where条件查询一页数据。</b>
	 * <p><b>详细说明：</b></p>
	 * <!-- 在此添加详细说明 -->
	 * 无。
	 * @param where where条件，允许为空
	 * @param sort 排序规则
	 * @param pageNum 页码(从1开始)
	 * @param pageSize 页大小
	 * @param excluded 排除的属性
	 * @return 一页数据
	 */
	default PageSet<T> findPage(Predicate where, Sort sort, long pageNum, int pageSize, String... excluded) {
		long count = count(where);
		List<T> list = findAll(where, sort, excluded);
		return PageSet.of(list, pageNum, pageSize, count);
	}
}
